// DHT-11 stuff
// Chris Baird 2020

#include <stm32f10x_gpio.h>
#include "delay.h"
#include "dht.h"

#define dhtpin (GPIO_Pin_10)
#define dhtstat (GPIO_ReadInputDataBit(GPIOB, dhtpin))

int dht_data[5];
extern GPIO_InitTypeDef GPIO_Conf;


int collect_weather_data (void)
{
  const unsigned char bits[9] = { 0, 1, 2, 4, 8, 16, 32, 64, 128 };
  unsigned int cnt;
  static int dhtinit = 1;

  if (dhtinit)			/* needs one second to power up */
    {
      dhtinit--;
      _delay_ms (1000);
    }

  GPIO_Conf.GPIO_Pin = dhtpin;
  GPIO_Conf.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Conf.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_Init(GPIOB, &GPIO_Conf);

  GPIO_ResetBits (GPIOB, dhtpin);
  _delay_ms (20);

  GPIO_SetBits (GPIOB, dhtpin);
  _delay_us (40);

  GPIO_Conf.GPIO_Pin = dhtpin;
  GPIO_Conf.GPIO_Mode = GPIO_Mode_IN_FLOATING; //GPIO_Mode_IPU;
  GPIO_Init(GPIOB, &GPIO_Conf);

  // wait for 1
  dht_data[4] = 255;		//  when there's no device
  for (cnt = 60000; !dhtstat && cnt; cnt--) continue;
  if (!cnt) return 0;

  // wait for 0
  dht_data[4] = 254;		// when something breaks..
  cnt = 60000;
  while (dhtstat && --cnt) continue;
  if (cnt == 0) return 0;

  GPIO_ResetBits (GPIOB, dhtpin); // hold the bus

  for (int i = 0; i < 5; i++)
    {
      unsigned char data = 0;

      for (int i = 8; i; i--)
	{
	  int p;

	  // wait for 1
	  for (cnt = 60000; !dhtstat && cnt; cnt--) continue;
	  if (!cnt) return 0;
	  cnt = 60000 - cnt;

	  // wait for 0
	  for (p = 0; dhtstat; p++) continue;

	  // determine if 1-wire bit was 0 (short pulse) | 1 (long)
	  if (p > (cnt>>1)) data |= bits[i];
	}
      dht_data[i] = data;
    }

  GPIO_SetBits (GPIOB, dhtpin); /* release the bus */

  unsigned char chk = (dht_data[0] + dht_data[1] + dht_data[2] + dht_data[3]) ^ dht_data[4];
  return !chk;
}
